Parser: Better debugging of lock errors ("Did you call Parser::parse recursively?")
authorBartosz Dziewoński <matma.rex@gmail.com>
Tue, 23 May 2017 12:48:32 +0000 (14:48 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Tue, 23 May 2017 12:50:13 +0000 (14:50 +0200)
Save the backtrace when locking, so that if some code tries locking again,
we can print the lock owner's backtrace for easier debugging.

Change-Id: I6e352b4aa5e7cb35825a66592f6c066d9e8b95c9

includes/parser/Parser.php

index ecee0e2..11392de 100644 (file)
@@ -245,7 +245,7 @@ class Parser {
        public $currentRevisionCache;
 
        /**
-        * @var bool Recursive call protection.
+        * @var bool|string Recursive call protection.
         * This variable should be treated as if it were private.
         */
        public $mInParse = false;
@@ -6073,9 +6073,13 @@ class Parser {
        protected function lock() {
                if ( $this->mInParse ) {
                        throw new MWException( "Parser state cleared while parsing. "
-                               . "Did you call Parser::parse recursively?" );
+                               . "Did you call Parser::parse recursively? Lock is held by: " . $this->mInParse );
                }
-               $this->mInParse = true;
+
+               // Save the backtrace when locking, so that if some code tries locking again,
+               // we can print the lock owner's backtrace for easier debugging
+               $e = new Exception;
+               $this->mInParse = $e->getTraceAsString();
 
                $recursiveCheck = new ScopedCallback( function() {
                        $this->mInParse = false;